/**
 * 
 */
package com.netflexitysolutions.amazonws.sdb.internal.operations;

import java.util.ArrayList;
import java.util.List;

import com.amazonaws.sdb.doc._2009_04_15.Attribute;
import com.amazonaws.sdb.doc._2009_04_15.ResponseMetadata;
import com.amazonaws.sdb.doc._2009_04_15.Select;
import com.amazonaws.sdb.doc._2009_04_15.SelectResponse;
import com.amazonaws.sdb.doc._2009_04_15.SelectResult;
import com.netflexitysolutions.amazonws.sdb.Item;
import com.netflexitysolutions.amazonws.sdb.SimpleDB;
import com.netflexitysolutions.amazonws.sdb.Statistics;

/**
 * @author netflexity
 *
 */
public class SelectOperation extends OperationExecutor<Select, List<Item>>{

	// Select expression.
	private String query;
	
	/**
	 * @param simpleDB
	 * @param query
	 * @param nextToken
	 */
	public SelectOperation(SimpleDB simpleDB, String query, String nextToken) {
		super(simpleDB);
		this.query = query;
		this.nextToken = nextToken;
	}
	
	/* (non-Javadoc)
	 * @see com.netflexitysolutions.amazonws.sdb.internal.OperationExecutor#call(java.lang.Object)
	 */
	@Override
	protected List<Item> call(Select request) {
		List<Item> items = new ArrayList<Item>();
		
		// Prepare request.
		request.setSelectExpression(query);
		request.setNextToken(nextToken);
		
		// Invoke operation.
		SelectResponse response = getSimpleDB().getService().select(request);
		if(response != null){
			ResponseMetadata metadata = response.getResponseMetadata();
			if(metadata != null){
				this.stats = new Statistics(metadata.getRequestId(), metadata.getBoxUsage());
			}
			SelectResult result = response.getSelectResult();
			if(result != null){
				this.nextToken = result.getNextToken();
				this.stats.setNextToken(this.nextToken);
				List<com.amazonaws.sdb.doc._2009_04_15.Item> selectedItems = result.getItem();
				for (com.amazonaws.sdb.doc._2009_04_15.Item selectedItem : selectedItems) {
					Item item = new Item();
					item.setIdentifier(selectedItem.getName());
					items.add(item);
					
					// Add attributes.
					List<Attribute> attributes = selectedItem.getAttribute();
					for (Attribute attribute : attributes) {
						item.addAttribute(attribute.getName(), attribute.getValue(), false);
					}
				}
				this.stats.setRecordCount(items.size());
			}
		}
		return items;
	}
	
	/**
	 * @return the stats
	 */
	public Statistics getStats() {
		return stats;
	}

	/**
	 * @return the query
	 */
	public String getQuery() {
		return query;
	}

	/**
	 * @param query the query to set
	 */
	public void setQuery(String query) {
		this.query = query;
	}

	/**
	 * @return the nextToken
	 */
	public String getNextToken() {
		return nextToken;
	}

	/**
	 * @param nextToken the nextToken to set
	 */
	public void setNextToken(String nextToken) {
		this.nextToken = nextToken;
	}
}
